package com.wpf.system.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wpf.system.common.response.ResultUtils;
import com.wpf.system.common.response.ResultVO;
import com.wpf.system.entity.Equipment;
import com.wpf.system.entity.EquipmentBuy;
import com.wpf.system.entity.Orders;
import com.wpf.system.entity.dto.BookRentBuySearchDTO;
import com.wpf.system.entity.dto.EquipmentBuyDTO;
import com.wpf.system.entity.vo.EquipmentBagVO;
import com.wpf.system.entity.vo.EquipmentBuyVO;
import com.wpf.system.entity.vo.PageVO;
import com.wpf.system.service.*;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/api/equipmentBuy")
public class EquipmentBuyController {

    @Resource
    private EquipmentBuyService equipmentBuyService;

    @Resource
    private EquipmentService equipmentService;

    @Resource
    private OrdersService ordersService;

    @Resource
    private BalanceJournalService balanceJournalService;

    @Resource
    private PointJournalService pointJournalService;

    @GetMapping("/chart")
    public ResultVO getEquipmentBuyChart(@RequestParam(value = "date",required=false) String date){
        return ResultUtils.success("请求出售图表数据成功",equipmentBuyService.getEquipmentBuyChartData(date));
    }

    @GetMapping("/todaySellTotal")
    public int getTurnover(@RequestParam("date") String time,@RequestParam("offset") int offset){
        Date date = DateUtil.offsetDay(DateUtil.parse(time),offset);
        QueryWrapper<EquipmentBuy> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status",2).between("update_time", DateUtil.beginOfDay(date),DateUtil.endOfDay(date));
        queryWrapper.or().eq("status",6).between("update_time", DateUtil.beginOfDay(date),DateUtil.endOfDay(date));
        queryWrapper.select("sum(number) as number");
        if(equipmentBuyService.getOne(queryWrapper)!=null){
            return equipmentBuyService.getOne(queryWrapper).getNumber();
        }else{
            return 0;
        }
    }

    @GetMapping("/list")
    public PageVO<EquipmentBuyVO> getAllEquipmentBuy(
            @RequestParam(value = "no",required=false) String no,
            @RequestParam(value = "uid",required=false) Long uid,
            @RequestParam(value = "name",required=false) String name,
            @RequestParam(value = "nid",required=false) String nid,
            @RequestParam(value = "username",required=false) String username,
            @RequestParam(value = "phone",required=false) String phone,
            @RequestParam(value = "startTime",required=false) String startTime,
            @RequestParam(value = "endTime",required=false) String endTime,
            @RequestParam(value = "page",required=false) int page,
            @RequestParam(value = "pageSize",required=false) int pageSize
    ){
        BookRentBuySearchDTO bookRentBuySearchDTO = new BookRentBuySearchDTO();
        bookRentBuySearchDTO.setNo(no);
        bookRentBuySearchDTO.setUid(uid);
        bookRentBuySearchDTO.setName(name);
        bookRentBuySearchDTO.setNid(nid);
        bookRentBuySearchDTO.setUsername(username);
        bookRentBuySearchDTO.setPhone(phone);
        bookRentBuySearchDTO.setStartTime(startTime);
        bookRentBuySearchDTO.setEndTime(endTime);
        bookRentBuySearchDTO.setPageSize(pageSize);
        //手动分页需要注意分页公式
        bookRentBuySearchDTO.setPage(Math.max((page - 1) * pageSize,0));

        List<EquipmentBuyVO> list = equipmentBuyService.getAllEquipmentBuy(bookRentBuySearchDTO);
        bookRentBuySearchDTO.setPage(null);
        bookRentBuySearchDTO.setPageSize(null);
        int total = equipmentBuyService.getAllEquipmentBuy(bookRentBuySearchDTO).size();
        PageVO<EquipmentBuyVO> equipmentRentListVO = new PageVO<>();
        equipmentRentListVO.setList(list);
        equipmentRentListVO.setTotal(total);
        return equipmentRentListVO;
    }

    @PostMapping
    public ResultVO addEquipmentBuy(@RequestBody List<EquipmentBuyDTO> equipmentBuyDTOList){
        List<Long> canBuyList = new ArrayList<>();
        for(EquipmentBuyDTO item : equipmentBuyDTOList ){
            Equipment equipment = equipmentService.getById(item.getEid());
            if(equipment.getNumber()>=item.getNumber()){
                equipment.setNumber(equipment.getNumber()-item.getNumber());
                EquipmentBuy equipmentBuy = new EquipmentBuy();
                equipmentBuy.setUid(item.getUid());
                equipmentBuy.setEid(item.getEid());
                equipmentBuy.setCost(item.getCost());
                equipmentBuy.setNumber(item.getNumber());
                if(equipmentService.updateById(equipment)&&equipmentBuyService.save(equipmentBuy)){
                    canBuyList.add(equipmentBuy.getId());
                }
            }
        }
        List<EquipmentBagVO> equipmentBuyVOList = equipmentBuyService.getBackEquipmentInfo(canBuyList);
        if(canBuyList.size()==equipmentBuyDTOList.size()&&canBuyList.size()>0){
            return ResultUtils.success("提交购买信息成功！请在1分钟内请确认订单无误！",equipmentBuyVOList);
        }else if(canBuyList.size()<equipmentBuyDTOList.size()&&canBuyList.size()>0){
            return ResultUtils.success("部分器材已无库存，以下器材仍可购买！请在1分钟内确认继续或取消此次购买！",equipmentBuyVOList);
        }else{
            return ResultUtils.error("很抱歉！该器材已无库存，可选择同类相似的器材");
        }
    }

    @PutMapping
    public ResultVO editEquipmentBuyStatus(@RequestBody EquipmentBuy equipmentBuy){
        int beforeUpdateStatus = equipmentBuyService.getById(equipmentBuy.getId()).getStatus();
        Orders orders = ordersService.getById(equipmentBuy.getOid());
        boolean flag;
        String msg = null;
        //如果是未支付的订单取消子项，则整个订单取消
        if(orders.getStatus()==0){
            equipmentBuyService.list(new LambdaQueryWrapper<EquipmentBuy>().eq(EquipmentBuy::getOid,orders.getId())).forEach(item->{
                item.setStatus(equipmentBuy.getStatus());
                equipmentBuyService.updateById(item);
            });
            orders.setStatus(2);
            orders.setCost(BigDecimal.valueOf(0));
            orders.setPoint(0L);
            flag = ordersService.updateById(orders);
            if(flag){
                msg = "已成功取消整个购买订单！";
            }else{
                msg = "取消整个购买订单失败！";
            }
        }else{
            flag = equipmentBuyService.updateById(equipmentBuy);
            switch (equipmentBuy.getStatus()){
                case 2:
                    if(flag){
                        msg = "领取码正确！请拿取对应新器材给用户";
                    }else{
                        msg = "领取码错误！";
                    }
                    break;
                case 5:
                    if(flag){
                        msg = "已提交退货申请！通过后请将购买器材归还";
                    }else{
                        msg = "提交退货申请失败！请再次尝试！";
                    }
                    break;
                case 6:
                    if(flag){
                        msg = "已拒绝用户的退货申请！";
                    }else{
                        msg = "拒绝退货申请失败！请再次尝试！";
                    }
                    break;
                case 3:
                case 7:
                case 8:
                    if(flag){
                        if(ObjectUtil.isNotNull(orders)&&orders.getStatus()!=0){
                            if(orders.getPoint()>0 || orders.getCost().compareTo(BigDecimal.valueOf(0))==1&&beforeUpdateStatus!=0){
                                if(orders.getPoint()>0){
                                    pointJournalService.pointInto(orders,2);
                                }
                                if(orders.getCost().compareTo(BigDecimal.valueOf(0))==1&&beforeUpdateStatus!=0){
                                    balanceJournalService.balanceInto(orders,2,equipmentBuy.getId());
                                }
                            }
                        }
                        //退还库存
                        Equipment equipment = equipmentService.getById(equipmentBuy.getEid());
                        equipment.setNumber(equipment.getNumber()+equipmentBuy.getNumber());
                        equipmentService.updateById(equipment);
                        //检查相同订单是否还有有效项，没有就关闭订单
                        LambdaQueryWrapper<EquipmentBuy> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(EquipmentBuy::getOid,orders.getId()).in(EquipmentBuy::getStatus,0,1,2,5,6);
                        if(equipmentBuyService.count(queryWrapper)==0){
                            orders.setStatus(2);
                            ordersService.updateById(orders);
                        }
                        if(equipmentBuy.getStatus()==3){
                            msg = "已同意用户的退货申请！请确认器材归还！";
                        }else{
                            msg = "取消交易成功！";
                        }
                    }else{
                        if(equipmentBuy.getStatus()==3){
                            msg = "同意退货申请失败！请再次尝试";
                        }else{
                            msg = "取消交易失败！";
                        }
                    }
                    break;
            }

        }

        if(flag){
            return ResultUtils.success(msg);
        }else{
            return ResultUtils.error(msg);
        }
    }

    @DeleteMapping("/{ids}")
    public ResultVO deleteEquipmentBuyByIds(@PathVariable("ids") String ids){
        List<Long> deleteIds = Convert.toList(Long.class,ids.split(","));
        for(Long id : deleteIds){
            //退还库存
            EquipmentBuy equipmentBuy = equipmentBuyService.getById(id);
            Equipment equipment = equipmentService.getById(equipmentBuy.getEid());
            equipment.setNumber(equipment.getNumber()+equipmentBuy.getNumber());
            equipmentService.updateById(equipment);
        }
        if(Convert.toBool(equipmentBuyService.deleteEquipmentBuyByIds(deleteIds))){
            return ResultUtils.success("取消购买订单成功！");
        }else{
            return ResultUtils.error("取消购买订单失败！");
        }
    }
}
